// Copyright (C) 2023 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
// 
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<北京小羊驼科技有限公司>，授权编号：<NT231212144350>，代码指纹：<A.702363430.550>，技术对接人微信：<ID: wxid_wbyootvkdcgj22>】
// 【授权寄送：<收件：苏先生、地址：北京市大兴区北京密码西区6号楼1单元301、电话：18613885610、邮箱：bd@huiyuanxiang-inc.com>】
// 
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
// 
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.rainbowchat.http.file;

import java.io.File;
import java.util.Timer;
import java.util.TimerTask;

import com.eva.epc.common.file.FileHelper;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.utils.LoggerFactory;
import com.x52im.rainbowchat.BaseConf;

/**
 * 定时转储服务端存储的客户端上传的图片、语音文件.
 * 
 * <p>
 * 为何要定时转储？目的是定期清理超时的聊天文件等（以防服务端的上传目录爆满）.
 * 
 * @author Jack Jiang
 * @since 2.4
 */
public class TimmingRestoreImgAndVoice
{
	private static TimmingRestoreImgAndVoice instance = null;
	
	private Timer timer = null;
	
	public static TimmingRestoreImgAndVoice getInstance()
	{
		if(instance == null)
			instance = new TimmingRestoreImgAndVoice();
		return instance;
	}
	
	public void doTaskOnece()
	{
		LoggerFactory.getLog().debug("[定时器1]======= 【1/2】图片、语音、短视频过期文件转储处理[开始] =======");
		long t = System.currentTimeMillis();
		
		// 先尝试转储过期的图片
		tryRestoreTimeoutFiles(BaseConf.getInstance().getDIR_USER_IMAGE_UPLOAD_UNREAD()
				, BaseConf.getInstance().getDIR_USER_IMAGE_UPLOAD_TIMEOUT());
		tryRestoreTimeoutFiles(BaseConf.getInstance().getDIR_USER_IMAGE_UPLOAD_READ()
				, BaseConf.getInstance().getDIR_USER_IMAGE_UPLOAD_TIMEOUT());
		// 再尝试转储过期的语音文件
		tryRestoreTimeoutFiles(BaseConf.getInstance().getDIR_USER_VOICE_UPLOAD_UNREAD()
				, BaseConf.getInstance().getDIR_USER_VOICE_UPLOAD_TIMEOUT());
		tryRestoreTimeoutFiles(BaseConf.getInstance().getDIR_USER_VOICE_UPLOAD_READ()
				, BaseConf.getInstance().getDIR_USER_VOICE_UPLOAD_TIMEOUT());
		// 再尝试转储过期的短视频文件
		tryRestoreTimeoutFiles(BaseConf.getInstance().getDIR_USER_SHORTVIDEO_UPLOAD()
				, BaseConf.getInstance().getDIR_USER_SHORTVIDEO_UPLOAD_TIMEOUT());
		
		LoggerFactory.getLog().debug("[定时器1]======= 【2/2】图片、语音、短视频过期文件转储处理[完成] ,[耗时："+(System.currentTimeMillis() - t)+"毫秒]");
	}
	
	/**
	 * 为保证没有被正常处理的语音临时文件不要老存放在SD卡上（占用空间）而所作的清理处理.
	 */
	private void tryRestoreTimeoutFiles(String srcDir, String destDir)
	{
		try
		{
			File voiceSavedDir = new File(srcDir);
			if(voiceSavedDir.exists())
			{
				File[] files = voiceSavedDir.listFiles();
				if(files != null && files.length > 0)
				{
					for(File f : files)
					{
						// 是文件
						if(f.isFile() && f.exists())
						{
							long delta = System.currentTimeMillis() - f.lastModified();
							
							String timeout = BaseConf.getInstance().getAUTO_TIMING_RESTORE_IMG_AND_VOICE_TIMEOUT();
							if(delta >= CommonUtils.getIntValue(timeout))
							{
								LoggerFactory.getLog().debug("[HTTP]文件"+f.getAbsolutePath()+"距今已"+delta
									+"毫秒(超过了最大生存期"+timeout+")了，即将被转储！");
//								f.delete();
								
								// 先把文件转储到新目录
								FileHelper.copyFile(f.getAbsolutePath(), destDir+f.getName());
								// 再把原文件删除
								FileHelper.deleteFile(f.getAbsolutePath());
							}
							else
							{
								LoggerFactory.getLog().debug("[HTTP]文件"+f.getAbsolutePath()+"距今只有"+delta
										+"毫秒(没有超过最大生存期"+timeout+")，无需被转储.");
							}
						}
					}
				}
			}
		}
		catch (Exception e)
		{
			LoggerFactory.getLog().warn("[HTTP]转储目录"+srcDir+"下的文件时出错了，"+e.getMessage(), e);
		}
	}
	
	public void start()
	{
		// ** 先确保之前定时任务被停止
		stop();
		
		// ** 启动定时任务
		timer = new Timer();
		// ** 以定长延迟的方式进行（即下一次执行是在本次执行结束之后开始计时）
		timer.schedule(new TimerTask() {
			@Override
			public void run()
			{
				doTaskOnece();
			}
		}
		// 首次执行时的延迟
		, 1000 * 60 * 10
		// 定时执行的时间间隔
		, CommonUtils.getIntValue(BaseConf.getInstance().getAUTO_TIMING_RESTORE_IMG_AND_VOICE_INTERVAL(), 10 * 60 * 10));
	}
	
	/**
	 * 无条件中断本定时器的运行。
	 */
	public void stop()
	{
		if(timer != null)
		{
			try{
				timer.cancel();
			}
			finally{
				timer = null;
			}
		}
	}
	
	/**
	 * 定时器是否正在运行中。
	 * 
	 * @return true表示是，否则定时器处于停止状态
	 */
	public boolean isRunning()
	{
		return timer != null;
	}
}
